#ifndef _TASKTIMER_H
#define _TASKTIMER_H

#include <map>
#include <mutex>
#include <mutex>
#include <functional>
#include <memory>

/* timeout task processing */

struct Msg;
struct cmp
{
    bool operator()(const struct timeval& v1, const struct timeval& v2) const
    {
        if (v1.tv_sec != v2.tv_sec) return v1.tv_sec < v2.tv_sec;

        if (v1.tv_usec != v2.tv_usec) return v1.tv_usec < v2.tv_usec;

        return false;
    }
};

struct TimePacker 
{
    std::weak_ptr<Msg> m_param;
    std::function<void(std::weak_ptr<Msg>)> m_func;

    TimePacker(std::weak_ptr<Msg> param, std::function<void(std::weak_ptr<Msg>)> func) :
        m_param(param),
        m_func(func)
    {

    }

    ~TimePacker()
    {

    }
};
typedef std::shared_ptr<TimePacker> TimePackerPtr;

class TaskTimer
{
public:
    static TaskTimer* Instance();
    ~TaskTimer();

    int shutdown();

    int AddTimeoutTask(
        struct timeval times, std::function<void(std::weak_ptr<Msg>)> m_func, std::weak_ptr<Msg> m_param
    );
    void HandleTimeoutTask();

private:
    class CGarbo
    {
    public:
        CGarbo()
        {
        }
        ~CGarbo()
        {
            if (TaskTimer::m_instance) delete TaskTimer::m_instance;
        }
    };
    static CGarbo Garbo;

private:
    TaskTimer();
    TaskTimer(const TaskTimer& other) {}
    TaskTimer& operator=(const TaskTimer& other) { return *this; }

    int spin_lock();
    int unlock();
private:

    static TaskTimer* m_instance;
    int m_timeSignal;
    int m_quit;

    pthread_spinlock_t   m_spin_lock;
    std::map<struct timeval, TimePackerPtr, cmp>  m_TimeTask;
};

#endif  //_TASKTIMER_H